//
//  UIIconButton.swift
//  demo_swift
//
//  Created by dongyx on 2023/5/25.
//

import UIKit

enum IconButtonStyle {
    case onlyIcon
    case onlyText
    // 水平排列 icon in leading
    case leading(itemSpace: CGFloat)
    // 水平排列 icon in leading
    case trailing(itemSpace: CGFloat)
    /// 垂直排列 icon in top
    case top(itemSpace: CGFloat)
    /// 垂直排列 icon in bottom
    case bottom(itemSpace: CGFloat)
    
    /// 是否水平排布
    var isHorizontal: Bool {
        switch self {
        case .top, .bottom:
            return false
        default:
            return true
        }
    }
    
}

private struct UIButtonInfoModel {
    var normalStr: String?
    var selectStr: String?
    
    var normalColor: UIColor?
    var selectColor: UIColor?
    
    var normalIcon: UIImage?
    var selectIcon: UIImage?
}

class UIIconButton: UIButton {
    
    private lazy var iconView: UIImageView = {
        let makeView = UIImageView()
        makeView.contentMode = .scaleAspectFit
        makeView.translatesAutoresizingMaskIntoConstraints = false
        return makeView
    }()
    
    private lazy var textLabel: UILabel = {
        let makeView = UILabel()
        makeView.translatesAutoresizingMaskIntoConstraints = false
        return makeView
    }()
    
    var iconSize: CGSize = CGSize(width: 30.0, height: 30.0) {
        didSet {
            updateSubViewsConstraints()
        }
    }
    
    //
    private var iconStyle: IconButtonStyle = .leading(itemSpace: 5.0) {
        didSet {
            updateSubViewsConstraints()
        }
    }
    
    private var infoModel = UIButtonInfoModel() {
        didSet {
            refreshSubviewsInfo()
        }
    }
    
    override var isSelected: Bool {
        didSet {
            refreshSubviewsInfo()
        }
    }
    
    // 对齐方式
    override var contentHorizontalAlignment: UIControl.ContentHorizontalAlignment {
        didSet {
            updateSubViewsConstraints()
        }
    }
    
    override var contentVerticalAlignment: UIControl.ContentVerticalAlignment {
        didSet {
            updateSubViewsConstraints()
        }
    }
    
    override var contentEdgeInsets: UIEdgeInsets {
        didSet {
            updateSubViewsConstraints()
        }
    }
    
    private var number_observation: NSKeyValueObservation?
    private var font_observation: NSKeyValueObservation?
    
    init(style: IconButtonStyle) {
        super.init(frame: .zero)
        
        self.iconStyle = style
        //        self.translatesAutoresizingMaskIntoConstraints = false
        
        addSubview(iconView)
        addSubview(textLabel)
        
        number_observation = self.titleLabel?.observe(\.numberOfLines, options: .new, changeHandler: { [weak self] sender, change in
            if let number = change.newValue {
                self?.textLabel.numberOfLines = number
            }
        })
        
        font_observation = self.titleLabel?.observe(\.font, options: .new, changeHandler: { [weak self] sender, change in
            self?.textLabel.font = change.newValue
        })
        
        updateSubViewsConstraints()
    }
    
    // super func
    override func setTitle(_ title: String?, for state: UIControl.State) {
        if state == .selected {
            infoModel.selectStr = title
        } else if state == .normal {
            infoModel.normalStr = title
        }
        refreshSubviewsInfo()
    }
    
    override func setTitleColor(_ color: UIColor?, for state: UIControl.State) {
        if state == .selected {
            infoModel.selectColor = color
        } else if state == .normal {
            infoModel.normalColor = color
        }
        refreshSubviewsInfo()
    }
    
    override func setImage(_ image: UIImage?, for state: UIControl.State) {
        if state == .selected {
            infoModel.selectIcon = image
        } else if state == .normal {
            infoModel.normalIcon = image
        }
        refreshSubviewsInfo()
    }
    
    override init(frame: CGRect) {
        fatalError("please use init(style:)")
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
}


private extension UIIconButton {
    
    //TODO: - 刷新子视图数据
    func refreshSubviewsInfo() {
        if self.isSelected {
            textLabel.text = infoModel.selectStr == nil ? infoModel.normalStr : infoModel.selectStr
            textLabel.textColor = infoModel.selectColor == nil ? infoModel.normalColor : infoModel.selectColor
            iconView.image = infoModel.selectIcon == nil ? infoModel.normalIcon : infoModel.selectIcon
        } else {
            textLabel.text = infoModel.normalStr
            textLabel.textColor = infoModel.normalColor
            iconView.image = infoModel.normalIcon
        }
    }
    
    //TOOD: - update style
    func updateSubViewsConstraints() {
        /// 移除已设置所有布局
        iconView.removeConstraints(iconView.constraints)
        textLabel.removeConstraints(textLabel.constraints)
        self.removeConstraints(self.constraints)
        
        // 设置大小
        iconView.widthAnchor.constraint(equalToConstant: iconSize.width).isActive = true
        iconView.heightAnchor.constraint(equalToConstant: iconSize.height).isActive = true
        
        iconView.isHidden = false
        textLabel.isHidden = false
        
        if iconStyle.isHorizontal {
            iconView.centerYAnchor.constraint(equalTo: self.centerYAnchor, constant: 0).isActive = true
            textLabel.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true
        } else {
            iconView.centerXAnchor.constraint(equalTo: self.centerXAnchor, constant: 0).isActive = true
            textLabel.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
        }
        
        let edgeInsets = contentEdgeInsets
        switch iconStyle {
        case .onlyIcon:
            textLabel.isHidden = true
            iconView.centerXAnchor.constraint(equalTo: self.centerXAnchor, constant: 0).isActive = true
        case .onlyText:
            iconView.isHidden = true
            textLabel.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
        case .leading(let itemSpace):
            if contentHorizontalAlignment == .center {
                /// 居中对齐
                textLabel.leadingAnchor.constraint(equalTo: iconView.trailingAnchor, constant: itemSpace).isActive = true
                textLabel.centerXAnchor.constraint(equalTo: self.centerXAnchor, constant: (itemSpace + iconSize.width)/2).isActive = true
            } else if contentHorizontalAlignment == .left || contentHorizontalAlignment == .leading {
                /// 左对齐
                self.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-\(edgeInsets.left)-[iconView]-\(itemSpace)-[textLabel]->=\(edgeInsets.right)-|", metrics: nil, views: ["iconView": iconView, "textLabel": textLabel]))
            } else if contentHorizontalAlignment == .right || contentHorizontalAlignment == .trailing {
                /// 右对齐
                self.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|->=\(edgeInsets.left)-[iconView]-\(itemSpace)-[textLabel]-\(edgeInsets.right)-|", metrics: nil, views: ["iconView": iconView, "textLabel": textLabel]))
            }
        case .trailing(let itemSpace):
            if contentHorizontalAlignment == .center {
                /// 居中对齐
                textLabel.trailingAnchor.constraint(equalTo: iconView.leadingAnchor, constant: -itemSpace).isActive = true
                textLabel.centerXAnchor.constraint(equalTo: self.centerXAnchor, constant: -(itemSpace + iconSize.width)/2).isActive = true
            } else if contentHorizontalAlignment == .left || contentHorizontalAlignment == .leading {
                /// 左对齐
                self.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-\(edgeInsets.left)-[textLabel]-\(itemSpace)-[iconView]->=\(edgeInsets.right)-|", metrics: nil, views: ["iconView": iconView, "textLabel": textLabel]))
            } else if contentHorizontalAlignment == .right || contentHorizontalAlignment == .trailing {
                /// 右对齐
                self.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|->=\(edgeInsets.left)-[textLabel]-\(itemSpace)-[iconView]-\(edgeInsets.right)-|", metrics: nil, views: ["iconView": iconView, "textLabel": textLabel]))
            }
        case .top(let itemSpace):
            if contentVerticalAlignment == .center {
                iconView.bottomAnchor.constraint(equalTo: textLabel.topAnchor, constant: -itemSpace).isActive = true
                textLabel.centerYAnchor.constraint(equalTo: self.centerYAnchor, constant: (itemSpace + iconSize.height)/2).isActive = true
            } else if contentVerticalAlignment == .top {
                /// 上
                self.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-\(edgeInsets.top)-[iconView]-\(itemSpace)-[textLabel]->=\(edgeInsets.bottom)-|", metrics: nil, views: ["iconView": iconView, "textLabel": textLabel]))
            } else if contentVerticalAlignment == .bottom {
                /// 下
                self.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|->=\(edgeInsets.top)-[iconView]-\(itemSpace)-[textLabel]-\(edgeInsets.bottom)-|", metrics: nil, views: ["iconView": iconView, "textLabel": textLabel]))
            }
            break
        case .bottom(let itemSpace):
            if contentVerticalAlignment == .center {
                iconView.topAnchor.constraint(equalTo: textLabel.bottomAnchor, constant: itemSpace).isActive = true
                textLabel.centerYAnchor.constraint(equalTo: self.centerYAnchor, constant: -(itemSpace + iconSize.height)/2).isActive = true
            } else if contentVerticalAlignment == .top {
                /// 上
                self.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-\(edgeInsets.top)-[textLabel]-\(itemSpace)-[iconView]->=\(edgeInsets.bottom)-|", metrics: nil, views: ["iconView": iconView, "textLabel": textLabel]))
            } else if contentVerticalAlignment == .bottom {
                /// 下
                self.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|->=\(edgeInsets.top)-[textLabel]-\(itemSpace)-[iconView]-\(edgeInsets.bottom)-|", metrics: nil, views: ["iconView": iconView, "textLabel": textLabel]))
            }
            break
        }
    }
    
}

fileprivate extension UIView {
    
    // 获取自动布局属性
    func constraint(attribute: NSLayoutConstraint.Attribute) -> NSLayoutConstraint? {
        for constraint in self.constraints {
            if constraint.firstAttribute == attribute {
                return constraint
            }
        }
        return nil
    }
    
}
